package com.zeng.sys.authmd.servicemodule.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zeng.nicecore.constant.IgnoreConstant;
import com.zeng.nicecore.util.BeanUtil;
import com.zeng.nicecore.util.IgnoreStringUtil;
import com.zeng.nicecore.wrapper.QWrapper;
import com.zeng.sys.authmd.apimodule.service.PermissionService;
import com.zeng.sys.authmd.apimodule.service.RolePermissionService;
import com.zeng.sys.authmd.apimodule.service.UserRoleService;
import com.zeng.sys.authmd.apimodule.service.com.zeng.sys.authmd.apimodule.constant.PermissionType;
import com.zeng.sys.authmd.apimodule.vo.PermissionVo;
import com.zeng.sys.authmd.apimodule.vo.RolePermissionVo;
import com.zeng.sys.authmd.servicemodule.convert.PermissionVoConvert;
import com.zeng.sys.authmd.servicemodule.convert.RoleVoConvert;
import com.zeng.sys.authmd.servicemodule.entity.Permission;
import com.zeng.sys.authmd.servicemodule.entity.RolePermission;
import com.zeng.sys.authmd.servicemodule.entity.UserRole;
import com.zeng.sys.authmd.servicemodule.mapper.PermissionMapper;
import com.zeng.sys.authmd.servicemodule.mapper.RoleMapper;
import com.zeng.sys.authmd.servicemodule.entity.Role;
import com.zeng.sys.authmd.apimodule.vo.RoleVo;
import com.zeng.sys.authmd.apimodule.service.RoleService;
import com.zeng.sys.authmd.servicemodule.mapper.UserRoleMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class RoleServiceImpl extends RoleVoConvert implements RoleService {

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    RolePermissionService rolePermissionService;

    @Autowired
    PermissionMapper permissionMapper;

    @Autowired
    UserRoleService userRoleService;


    @Override
    public RoleVo addOne(RoleVo roleVo) {
        Role role = Role.builder().build();
        BeanUtils.copyProperties(roleVo, role, IgnoreStringUtil.ignoreExclude());
        int insert = roleMapper.insert(role);
        return BeanUtil.beanToVo(role, roleVo);
    }

    @Override
    public RoleVo getOneByCode(String code) {

        Role role = this.roleMapper.selectById(code);
        RoleVo roleVo = BeanUtil.beanToVo(role, new RoleVo());

        return roleVo;
    }

    @Override
    public Integer update(RoleVo roleVo) {
        Role role = BeanUtil.VoToBean(roleVo,
                new Role(),
                IgnoreStringUtil.ignoreExclude(IgnoreConstant.code.getValue()));
        return this.roleMapper.updateById(role);
    }

    @Override
    public Integer delete(String code) {
        rolePermissionService.deleteByRoleCode(code);
        userRoleService.deleteByRoleCode(code);
        return this.roleMapper.deleteById(code);
    }

    @Override
    public Integer batchDelete(List<String> codes) {
        rolePermissionService.batchDeleteByRoleCodes(codes);
        userRoleService.batchDeleteByRoleCodes(codes);
        return this.roleMapper.deleteBatchIds(codes);
    }

    @Override
    public List<RoleVo> findPage(Page page, RoleVo roleVo) {
        Role role = BeanUtil.VoToBean(roleVo, new Role());
        this.roleMapper.selectPage(page, this.getWrapper(roleVo));
        List orders = page.getRecords();
        List<RoleVo> roleVos = new ArrayList<>();
        orders.forEach(e -> {
            roleVos.add(BeanUtil.beanToVo(e, new RoleVo()));
        });
        page.setRecords(null);
        return roleVos;
    }

    @Override
    public Integer count(RoleVo roleVo) {
        Integer integer = this.roleMapper.selectCount(this.getWrapper(roleVo));
        return integer;
    }

    @Override
    public RoleVo detailRoleVoAndPermission(String code) {
        RoleVo role = getOneByCode(code);
        List<RolePermissionVo> rolePermissionVos = rolePermissionService.findAll(RolePermissionVo.builder().roleCode(code).build());
        List<String> permissionCodes = rolePermissionVos.stream().map(RolePermissionVo::getPermissionCode).collect(Collectors.toList());

        List<Permission> permissions = Collections.emptyList();
        if (permissionCodes.size() > 0) {
            QueryWrapper<Permission> queryWrapper = new QWrapper();
            queryWrapper.in("code", permissionCodes);
            permissions = permissionMapper.selectList(queryWrapper);
        }

        PermissionVoConvert permissionVoConvert = new PermissionVoConvert();
        List<PermissionVo> permissionVos = permissionVoConvert.toPermissionVoList(permissions);

        Map<String, List<PermissionVo>> collect = permissionVos.stream().collect(Collectors.groupingBy(PermissionVo::getType));
        for (String s : collect.keySet()) {
            if (s.equals(PermissionType.API)) {
                role.setApiCodes(collect.get(s).stream().map(PermissionVo::getCode).collect(Collectors.toList()));
            }
            if (s.equals(PermissionType.MENU)) {
                role.setMenuCodes(collect.get(s).stream().map(PermissionVo::getCode).collect(Collectors.toList()));
            }
        }
        return role;
    }

    @Override
    public List<RoleVo> listByCodes(List<String> codes) {
        if (CollectionUtils.isEmpty(codes)) {
            return Collections.emptyList();
        }
        AbstractWrapper wrapper = getWrapper(null);
        wrapper.in("code", codes);
        return toList(roleMapper.selectList(wrapper));
    }

    public AbstractWrapper getWrapper(RoleVo roleVo) {
        QueryWrapper<Role> wrapper = new QWrapper<>();
        if (roleVo != null) {

        }
        return wrapper;
    }

}
